local strict = ...

function strict.make_strict(table)

	local mt = getmetatable(table)
	if mt == nil then
	  mt = {}
	  setmetatable(table, mt)
	end

	table.__STRICT = true
	mt.__declared = {}

	mt.__newindex = function (t, n, v)
	  if t.__STRICT and not mt.__declared[n] then
		local w = debug.getinfo(2, "S").what
		if w ~= "main" and w ~= "C" then
		  error("assign to undeclared variable '"..n.."' in "..w, 2)
		end
		mt.__declared[n] = true
	  end
	  rawset(t, n, v)
	end
  
	mt.__index = function (t, n)
	  if not mt.__declared[n] and debug.getinfo(2, "S").what ~= "C" then
		error("variable '"..n.."' is not declared", 2)
	  end
	  return rawget(t, n)
	end

	rawset(table, "global", function(...)
	   for _, v in ipairs{...} do mt.__declared[v] = true end
	end)
end

return strict